{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BspwgQKL3Na8"
      },
      "source": [
        "<font face=\"Times New Roman\" size=5><div dir=rtl align=center>\n",
        "<font face=\"Times New Roman\" size=5>\n",
        "In The Name of God\n",
        "</font>\n",
        "<br> <br>\n",
        "<img src=\"https://logoyar.com/content/wp-content/uploads/2021/04/sharif-university-logo.png\" alt=\"University Logo\" width=\"150\" height=\"150\">\n",
        "<br>\n",
        "<font face=\"Times New Roman\" size=4 align=center>\n",
        "Sharif University of Technology - Department of Computer\n",
        "</font>\n",
        "<br> <br>\n",
        "<font color=\"#008080\" size=5>\n",
        "Introduction to Machine Learning\n",
        "</font>\n",
        "\n",
        "<hr/> <br>\n",
        "<font color=\"#800080\" size=6>\n",
        "Chapter 1: Linear Regression\n",
        "<br>\n",
        "</font>\n",
        "<br>\n",
        "<font face=\"Times New Roman\" size=4>\n",
        ":authors <br>\n",
        "<b>Amirmohammad Isazadeh - Seyyed Alireza Ghazanfari</b>\n",
        "</font>\n",
        "<hr>\n",
        "</div></font>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "i6NrAXONPtcR"
      },
      "source": [
        "<font  size=5><div dir=ltr>\n",
        "<font face=\"Times New Roman\" color=\"#008080\" size=5>**Table of Contents**</font>\n",
        "<br>\n",
        "\n",
        "<font size=4>\n",
        "<ul>\n",
        "    <li>\n",
        "        <a href=\"#1\">\n",
        "            1. Linear Regression\n",
        "        </a>\n",
        "    </li>\n",
        "    <ul>\n",
        "          <li>\n",
        "                <a href=\"#1-1\">\n",
        "                    1-1. From Scratch\n",
        "                </a>\n",
        "            </li>\n",
        "        <ul>\n",
        "            <li>\n",
        "                <a href=\"#1-1-1\">\n",
        "                    1-1-1. Closed Form\n",
        "                </a>\n",
        "            </li>\n",
        "            <li>\n",
        "                <a href=\"#1-1-2\">\n",
        "                    1-1-2. Using Optimization Function (Gradient Descent)\n",
        "                </a>\n",
        "            </li>\n",
        "        </ul>\n",
        "        </ul>\n",
        "    <li>\n",
        "        <a href=\"#2\">\n",
        "            2. Beyond Linear Regression\n",
        "        </a>\n",
        "    </li>\n",
        "    <ul>\n",
        "        <li>\n",
        "            <a href=\"#2-1\">\n",
        "                2-1 Elastic Net\n",
        "            </a>\n",
        "        </li>\n",
        "        <ul>\n",
        "            <li>\n",
        "                <a href=\"#2-1-1\">\n",
        "                    2-1-1 Lasso VS Ridge\n",
        "                </a>\n",
        "            </li>\n",
        "        </ul>\n",
        "    </ul>\n",
        "</ul>\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "sBzocXtIiTbu"
      },
      "source": [
        "<font face=\"Times New Roman\"><div id=\"1\">\n",
        "# <font color=\"#800080\" size=6>**1. Linear Regression**</font>\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rYaiPL1plrDm"
      },
      "source": [
        "<font face=\"Times New Roman\"><div id=\"1-1\">\n",
        "## <font color=\"#800080\" size=6>**1-1. From Scratch** </font>\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "swwrxuSMAESj"
      },
      "source": [
        "#### <font color=\"#008080\" face=\"Times New Roman\" size=4>**Dataset**</font>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ju9aCx5yAESj"
      },
      "source": [
        "##### <font color=\"#008080\" face=\"Times New Roman\" size=4> - Introduction to Dataset </font>\n",
        "\n",
        "<font face=\"Times New Roman\" size=3>\n",
        "To estimate the productivity of apples and oranges, we will use a simple dataset containing metrics like temperature, rainfall, and humidity across different regions.\n",
        "</font>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gYuiA7fFAESk"
      },
      "source": [
        "##### <font color=\"#008080\" face=\"Times New Roman\" size=4> - Loading Dataset </font>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "FybchF26AESk"
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "# dataset (temp, rainfall, humidity, apples, oranges)\n",
        "df = np.array([[73, 67, 43, 56, 70],\n",
        "                   [91, 88, 64, 81, 101],\n",
        "                   [87, 134, 58, 119, 133],\n",
        "                   [102, 43, 37, 22, 37],\n",
        "                   [69, 96, 70, 103, 119]], dtype='float32')\n",
        "\n",
        "# reigons which are used as indexes\n",
        "regions = [\"Semnan\", \"Golestan\", \"Gilan\", \"Ghazvin\", \"Mazandaran\"]\n",
        "# parameters\n",
        "columns = [\"Temp(F)\", \"Rainfall(mm)\", \"Humidity(%)\", \"Apples(ton)\", \"Oranges(ton)\"]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 226
        },
        "id": "dILYYF3KwZUG",
        "outputId": "b4cff681-4be1-4734-f067-d9c231b62a1c"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "            Temp(F)  Rainfall(mm)  Humidity(%)  Apples(ton)  Oranges(ton)\n",
              "Semnan         73.0          67.0         43.0         56.0          70.0\n",
              "Golestan       91.0          88.0         64.0         81.0         101.0\n",
              "Gilan          87.0         134.0         58.0        119.0         133.0\n",
              "Ghazvin       102.0          43.0         37.0         22.0          37.0\n",
              "Mazandaran     69.0          96.0         70.0        103.0         119.0"
            ],
            "text/html": [
              "\n",
              "  <div id=\"df-aba489fe-0b32-497f-9b99-76ea414febf2\" class=\"colab-df-container\">\n",
              "    <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Temp(F)</th>\n",
              "      <th>Rainfall(mm)</th>\n",
              "      <th>Humidity(%)</th>\n",
              "      <th>Apples(ton)</th>\n",
              "      <th>Oranges(ton)</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>Semnan</th>\n",
              "      <td>73.0</td>\n",
              "      <td>67.0</td>\n",
              "      <td>43.0</td>\n",
              "      <td>56.0</td>\n",
              "      <td>70.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Golestan</th>\n",
              "      <td>91.0</td>\n",
              "      <td>88.0</td>\n",
              "      <td>64.0</td>\n",
              "      <td>81.0</td>\n",
              "      <td>101.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Gilan</th>\n",
              "      <td>87.0</td>\n",
              "      <td>134.0</td>\n",
              "      <td>58.0</td>\n",
              "      <td>119.0</td>\n",
              "      <td>133.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Ghazvin</th>\n",
              "      <td>102.0</td>\n",
              "      <td>43.0</td>\n",
              "      <td>37.0</td>\n",
              "      <td>22.0</td>\n",
              "      <td>37.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Mazandaran</th>\n",
              "      <td>69.0</td>\n",
              "      <td>96.0</td>\n",
              "      <td>70.0</td>\n",
              "      <td>103.0</td>\n",
              "      <td>119.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "    <div class=\"colab-df-buttons\">\n",
              "\n",
              "  <div class=\"colab-df-container\">\n",
              "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-aba489fe-0b32-497f-9b99-76ea414febf2')\"\n",
              "            title=\"Convert this dataframe to an interactive table.\"\n",
              "            style=\"display:none;\">\n",
              "\n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
              "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
              "  </svg>\n",
              "    </button>\n",
              "\n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    .colab-df-buttons div {\n",
              "      margin-bottom: 4px;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "    <script>\n",
              "      const buttonEl =\n",
              "        document.querySelector('#df-aba489fe-0b32-497f-9b99-76ea414febf2 button.colab-df-convert');\n",
              "      buttonEl.style.display =\n",
              "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "      async function convertToInteractive(key) {\n",
              "        const element = document.querySelector('#df-aba489fe-0b32-497f-9b99-76ea414febf2');\n",
              "        const dataTable =\n",
              "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                    [key], {});\n",
              "        if (!dataTable) return;\n",
              "\n",
              "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "          + ' to learn more about interactive tables.';\n",
              "        element.innerHTML = '';\n",
              "        dataTable['output_type'] = 'display_data';\n",
              "        await google.colab.output.renderOutput(dataTable, element);\n",
              "        const docLink = document.createElement('div');\n",
              "        docLink.innerHTML = docLinkHtml;\n",
              "        element.appendChild(docLink);\n",
              "      }\n",
              "    </script>\n",
              "  </div>\n",
              "\n",
              "\n",
              "<div id=\"df-75836478-bbd1-4207-9617-0df63be46c23\">\n",
              "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-75836478-bbd1-4207-9617-0df63be46c23')\"\n",
              "            title=\"Suggest charts.\"\n",
              "            style=\"display:none;\">\n",
              "\n",
              "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "     width=\"24px\">\n",
              "    <g>\n",
              "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
              "    </g>\n",
              "</svg>\n",
              "  </button>\n",
              "\n",
              "<style>\n",
              "  .colab-df-quickchart {\n",
              "      --bg-color: #E8F0FE;\n",
              "      --fill-color: #1967D2;\n",
              "      --hover-bg-color: #E2EBFA;\n",
              "      --hover-fill-color: #174EA6;\n",
              "      --disabled-fill-color: #AAA;\n",
              "      --disabled-bg-color: #DDD;\n",
              "  }\n",
              "\n",
              "  [theme=dark] .colab-df-quickchart {\n",
              "      --bg-color: #3B4455;\n",
              "      --fill-color: #D2E3FC;\n",
              "      --hover-bg-color: #434B5C;\n",
              "      --hover-fill-color: #FFFFFF;\n",
              "      --disabled-bg-color: #3B4455;\n",
              "      --disabled-fill-color: #666;\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart {\n",
              "    background-color: var(--bg-color);\n",
              "    border: none;\n",
              "    border-radius: 50%;\n",
              "    cursor: pointer;\n",
              "    display: none;\n",
              "    fill: var(--fill-color);\n",
              "    height: 32px;\n",
              "    padding: 0;\n",
              "    width: 32px;\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart:hover {\n",
              "    background-color: var(--hover-bg-color);\n",
              "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "    fill: var(--button-hover-fill-color);\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart-complete:disabled,\n",
              "  .colab-df-quickchart-complete:disabled:hover {\n",
              "    background-color: var(--disabled-bg-color);\n",
              "    fill: var(--disabled-fill-color);\n",
              "    box-shadow: none;\n",
              "  }\n",
              "\n",
              "  .colab-df-spinner {\n",
              "    border: 2px solid var(--fill-color);\n",
              "    border-color: transparent;\n",
              "    border-bottom-color: var(--fill-color);\n",
              "    animation:\n",
              "      spin 1s steps(1) infinite;\n",
              "  }\n",
              "\n",
              "  @keyframes spin {\n",
              "    0% {\n",
              "      border-color: transparent;\n",
              "      border-bottom-color: var(--fill-color);\n",
              "      border-left-color: var(--fill-color);\n",
              "    }\n",
              "    20% {\n",
              "      border-color: transparent;\n",
              "      border-left-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "    }\n",
              "    30% {\n",
              "      border-color: transparent;\n",
              "      border-left-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "      border-right-color: var(--fill-color);\n",
              "    }\n",
              "    40% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "    }\n",
              "    60% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "    }\n",
              "    80% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "      border-bottom-color: var(--fill-color);\n",
              "    }\n",
              "    90% {\n",
              "      border-color: transparent;\n",
              "      border-bottom-color: var(--fill-color);\n",
              "    }\n",
              "  }\n",
              "</style>\n",
              "\n",
              "  <script>\n",
              "    async function quickchart(key) {\n",
              "      const quickchartButtonEl =\n",
              "        document.querySelector('#' + key + ' button');\n",
              "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
              "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
              "      try {\n",
              "        const charts = await google.colab.kernel.invokeFunction(\n",
              "            'suggestCharts', [key], {});\n",
              "      } catch (error) {\n",
              "        console.error('Error during call to suggestCharts:', error);\n",
              "      }\n",
              "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
              "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
              "    }\n",
              "    (() => {\n",
              "      let quickchartButtonEl =\n",
              "        document.querySelector('#df-75836478-bbd1-4207-9617-0df63be46c23 button');\n",
              "      quickchartButtonEl.style.display =\n",
              "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "    })();\n",
              "  </script>\n",
              "</div>\n",
              "    </div>\n",
              "  </div>\n"
            ]
          },
          "metadata": {},
          "execution_count": 2
        }
      ],
      "source": [
        "# We use pandas to represent dataset\n",
        "import pandas as pd\n",
        "\n",
        "# Creating dataframe using variable columns as columns and regions as index\n",
        "df = pd.DataFrame(df, columns=columns, index=regions)\n",
        "\n",
        "df"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0BrjWqO-AESk"
      },
      "source": [
        "##### <font color=\"#008080\" face=\"Times New Roman\" size=4> - Pre-Processing Dataset</font>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "-mpV4390AESl",
        "outputId": "06f04a07-ddc5-4804-9412-103bf36aba6d"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[  1.,  73.,  67.,  43.],\n",
              "       [  1.,  91.,  88.,  64.],\n",
              "       [  1.,  87., 134.,  58.],\n",
              "       [  1., 102.,  43.,  37.],\n",
              "       [  1.,  69.,  96.,  70.]])"
            ]
          },
          "metadata": {},
          "execution_count": 3
        }
      ],
      "source": [
        "# Separate dataset to two parts: X (inputs) - Y (productivity amount)\n",
        "X = df.iloc[:, :3].to_numpy()\n",
        "Y = df.iloc[:, 3:].to_numpy()\n",
        "\n",
        "# Based on Y = X * W + b the element of b just add a constant value to XW so we can add 1 to each row of X without any change in the output\n",
        "X = np.append(np.ones((5, 1)), X , axis=1)\n",
        "X"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "E5LZv8WxAESl"
      },
      "source": [
        "<font face=\"Times New Roman\"><div id=\"1-1-1\">\n",
        "### <font color=\"#800080\" size=5>**1-1-1. Closed Form**</font>\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "LpEmhZsmAESl"
      },
      "outputs": [],
      "source": [
        "# Closed form of Linear Regression Implementation\n",
        "\n",
        "# A function to implement its equation and return predicted W\n",
        "def normal_equation(X, Y):\n",
        "    W = np.dot((np.linalg.inv(np.dot(X.T,X))), np.dot(X.T,Y))\n",
        "    return W\n",
        "\n",
        "# .dot() represent matrix multiplication in numpy\n",
        "def lr_predict(X, W):\n",
        "    return np.dot(X, W)\n",
        "\n",
        "# Main function of closed form: it gets X and Y and returns its predictions correspond to input X\n",
        "def closed_form_lr(X, Y):\n",
        "    W = normal_equation(X, Y)\n",
        "    predictions = lr_predict(X, W)\n",
        "    return predictions\n",
        "\n",
        "# MSE loss\n",
        "def mse_loss(pred, real):\n",
        "    diff = pred - real\n",
        "    return np.sum(diff * diff) / diff.size"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DCicBNv3AESm"
      },
      "source": [
        "#### <font color=\"#008080\" face=\"Times New Roman\" size=4>**Evaluation**</font>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "n2ViYLYjAESn"
      },
      "source": [
        "##### <font color=\"#008080\" face=\"Times New Roman\" size=4> - Prediction</font>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "5Ojfx5_ewZUW"
      },
      "outputs": [],
      "source": [
        "predictions = closed_form_lr(X, Y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6fweiFAXAESn"
      },
      "source": [
        "##### <font color=\"#008080\" face=\"Times New Roman\" size=4> - Loss </font>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "brnmUn7rAESn",
        "outputId": "698922d2-66a7-4d53-c260-e378d794baae"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "0.4831212220582056"
            ]
          },
          "metadata": {},
          "execution_count": 6
        }
      ],
      "source": [
        "mse_loss(predictions, Y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "68iIHGEgAl1w"
      },
      "source": [
        "<font face=\"Times New Roman\"><div id=\"1-1-2\">\n",
        "### <font color=\"#800080\" size=5>**1-1-2. Using Optimization Function (Gradient Descent)**</font>\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "14oWGLnbAl1y"
      },
      "source": [
        "#### <font color=\"#008080\" face=\"Times New Roman\" size=4>**Start with random weights**</font>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ozKb37LXAl1y",
        "outputId": "69486ea1-fd6c-4ce0-9c50-1afd93a51e9e"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[0.51917106, 0.14036571],\n",
              "       [0.0524824 , 0.72269975],\n",
              "       [0.95922933, 0.17546878],\n",
              "       [0.83931093, 0.48137782]])"
            ]
          },
          "metadata": {},
          "execution_count": 7
        }
      ],
      "source": [
        "# Random initialization for weights\n",
        "W = np.random.rand(4, 2)\n",
        "W"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "yuMQBykZwZUe",
        "outputId": "39479d3b-1273-4084-9bcb-bf88845c9e74"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[104.70912098,  85.35310177],\n",
              "       [143.42314954, 112.15547579],\n",
              "       [182.30190351, 114.44797402],\n",
              "       [ 78.173741  ,  99.21187668],\n",
              "       [154.97823704, 100.54809855]])"
            ]
          },
          "metadata": {},
          "execution_count": 8
        }
      ],
      "source": [
        "# Use lr_predict from last section to find predictions by new weights\n",
        "predictions = lr_predict(X, W)\n",
        "predictions"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Ha7yR0A-wZUg",
        "outputId": "12295bcd-f45e-4fb2-fd15-275e5e283f65"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "2104.871566484253\n"
          ]
        }
      ],
      "source": [
        "# Calculate loss of our predictions\n",
        "loss = mse_loss(predictions, Y)\n",
        "print(loss)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1pM7GWcCwZUi"
      },
      "source": [
        "#### <font color=\"#008080\" face=\"Times New Roman\" size=4>**Gradient Descent**</font>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "id": "9eFBz9ObwZUj"
      },
      "outputs": [],
      "source": [
        "# Implementation of gradient\n",
        "def calc_gradient(X, error):\n",
        "    gradient = np.dot(X.T, error)\n",
        "    return gradient\n",
        "\n",
        "# Implementation of updating weights by using their gradient\n",
        "def update_weights(W, lr, gradient):\n",
        "    new_weights = W - lr * gradient\n",
        "    return new_weights"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "osVXNTRxAl1y"
      },
      "source": [
        "#### <font color=\"#008080\" face=\"Times New Roman\" size=4>**Train**</font>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "id": "zXCt34qrAl1z"
      },
      "outputs": [],
      "source": [
        "def train_model_lr_gd(X, Y, W, n_epoches, lr):\n",
        "    losses = []\n",
        "    for i in range(n_epoches):\n",
        "        # generating the predictions\n",
        "        predictions = lr_predict(X, W)\n",
        "        error = predictions - Y\n",
        "        # calculating the loss\n",
        "        loss = mse_loss(predictions, Y)\n",
        "        # adding the loss to our loss list\n",
        "        losses.append(loss)\n",
        "        # calculating gradients\n",
        "        gradient = calc_gradient(X, error) / Y.size\n",
        "        # updating weights and biases\n",
        "        W = update_weights(W, lr, gradient)\n",
        "    return W, losses"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UNVQE4NhAl1z"
      },
      "source": [
        "#### <font color=\"#008080\" face=\"Times New Roman\" size=4>**Test**</font>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "aGTyxoTtAl1z",
        "outputId": "67266cc7-86b6-4b76-dfc4-9f3b339e9db4"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "0.5253812078012265\n"
          ]
        }
      ],
      "source": [
        "# Use our model with learning rate 1e-5 and 10000 epochs and keep all loss values\n",
        "lr = 1e-5\n",
        "n_epoches = 10000\n",
        "W, losses = train_model_lr_gd(X, Y, W, n_epoches, lr)\n",
        "print(losses[-1])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SULBwRA6Al10"
      },
      "source": [
        "#### <font color=\"#008080\" face=\"Times New Roman\" size=4>**Visualization**</font>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "cellView": "form",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 54
        },
        "id": "ib8Or3t8Al11",
        "outputId": "247dd5cd-f02a-4715-9c99-67a7f06212d7"
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ],
            "image/png": "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2bNnO+/vuecexcfHq3fv3tq8eXOtFecGHlZVAwBg3SkFoocfflhRUVGSpLy8PE2dOlVTpkxRYmKi7rzzzlotEAAAoK6FncqHtmzZonbt2kmS3nrrLQ0bNkwjR45Unz59dOGFF9Zmfa7BomoAAOw5pRGimJgY7dixQ5I0d+5c/frXv5YkRUZGau/evbVXnQswYQYAgH2nNEL061//Wr///e+Vnp6uDRs26OKLL5YkrV69Wq1bt67N+gAAAOrcKY0QTZ06VRkZGfr+++/1xhtvqGnTppKkFStW6JprrqnVAk97B4eIDHNmAABYc0ojRPHx8XrmmWeO2H7//ff/4oIAAADq2ymNEM2ZM0effPKJ837q1Kk677zzdO211+rHH3+steLchPEhAADsOaVANHbsWPl8PknSypUrddddd+niiy9WQUGBxowZU6sFnu5YVA0AgH2nNGVWUFCgLl26SJLeeOMNXXLJJXr44Yf1+eefOwusAQAAGopTGiGKiIjQnj17JEkffvihBg0aJElKSEhwRo5wclhTDQCAPac0QtS3b1+NGTNGffr00bJlyzR9+nRJ0oYNG9SiRYtaLfB0x6M7AACw75RGiJ555hmFhYXp3//+t5599lk1b95ckvT+++9r8ODBtVqgWxiWVQMAYM0pjRC1bNlSs2bNOmL7448//osLchvGhwAAsO+URogkqbq6Wm+88YYeeughPfTQQ5o5c6aqq6tP6hiLFi3SpZdeqtTUVHk8Hr311lsB+40xmjBhgpo1a6aoqChlZmZq48aNAW127typ7OxsxcbGKj4+XiNGjFB5eXlAm6+++kr9+vVTZGSk0tLSNGXKlFM6ZwAAcHo6pUC0adMmde7cWcOHD9ebb76pN998U9ddd53OOussff311yd8nN27d+vcc8/V1KlTj7p/ypQpeuqpp/Tcc89p6dKlatSokbKysrRv3z6nTXZ2tlavXq3c3FzNmjVLixYt0siRI539Pp9PgwYNUqtWrbRixQo9+uijmjRpkp5//vlTOfW6w4wZAAD2mFMwZMgQM3jwYLNjxw5n2w8//GAGDx5sLr744lM5pJFkZs6c6bz3+/0mJSXFPProo8620tJS4/V6zauvvmqMMWbNmjVGkvnss8+cNu+//77xeDxm69atxhhj/v73v5smTZqYiooKp824ceNMx44dj1nLvn37TFlZ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FBcX2y4taGVlZZkXX3zRrFq1yuTn55uLL77YtGzZ0pSXlzttbrnlFpOWlmbmzZtnli9fbnr16mV69+7t7K+qqjJnn322yczMNF988YV57733TGJiohk/frzT5ptvvjHR0dFmzJgxZs2aNebpp582oaGhZs6cOfV6vsFg2bJlpnXr1uacc84xd9xxh7Odfv7ldu7caVq1amVuvPFGs3TpUvPNN9+YDz74wGzatMlp88gjj5i4uDjz1ltvmS+//NJcdtllpk2bNmbv3r1Om8GDB5tzzz3XLFmyxHz88cemXbt25pprrnH2l5WVmeTkZJOdnW1WrVplXn31VRMVFWX++7//u17P15a//OUvpmnTpmbWrFmmoKDAzJgxw8TExJgnn3zSaUM/n5r33nvP/PnPfzZvvvmmkWRmzpwZsL+++nXx4sUmNDTUTJkyxaxZs8bce++9Jjw83KxcufKkzodAZEmPHj1MTk6O8766utqkpqaayZMnW6yqYSkpKTGSzMKFC40xxpSWlprw8HAzY8YMp83atWuNJJOXl2eMOfA/cEhIiCkqKnLaPPvssyY2NtZUVFQYY4y55557zFlnnRXwXb/97W9NVlZWXZ9SUNm1a5dp3769yc3NNQMGDHACEf1cO8aNG2f69u17zP1+v9+kpKSYRx991NlWWlpqvF6vefXVV40xxqxZs8ZIMp999pnT5v333zcej8ds3brVGGPM3//+d9OkSROn32u+u2PHjrV9SkFp6NCh5qabbgrYduWVV5rs7GxjDP1cW34aiOqzX6+66iozdOjQgHp69uxpbr755pM6B6bMLNi/f79WrFihzMxMZ1tISIgyMzOVl5dnsbKGpaysTJKUkJAgSVqxYoUqKysD+rVTp05q2bKl0695eXnq2rWrkpOTnTZZWVny+XxavXq10+bwY9S0cdvfTU5OjoYOHXpEX9DPteOdd95R9+7d9Z//+Z9KSkpSenq6/ud//sfZX1BQoKKiooA+iouLU8+ePQP6OT4+Xt27d3faZGZmKiQkREuXLnXa9O/fXxEREU6brKwsrV+/Xj/++GNdn6Z1vXv31rx587RhwwZJ0pdffqlPPvlEQ4YMkUQ/15X67Nfa+reEQGTBDz/8oOrq6oBfFpKUnJysoqIiS1U1LH6/X6NHj1afPn109tlnS5KKiooUERGh+Pj4gLaH92tRUdFR+71m3/Ha+Hw+7d27ty5OJ+i89tpr+vzzzzV58uQj9tHPteObb77Rs88+q/bt2+uDDz7Qrbfeqttvv10vvfSSpEP9dLx/J4qKipSUlBSwPywsTAkJCSf1d3E6+9Of/qSrr75anTp1Unh4uNLT0zV69GhlZ2dLop/rSn3267HanGy/87R7NEg5OTlatWqVPvnkE9ulnHa2bNmiO+64Q7m5uYqMjLRdzmnL7/ere/fuevjhhyVJ6enpWrVqlZ577jndcMMNlqs7fbz++ut6+eWX9corr+iss85Sfn6+Ro8erdTUVPoZARghsiAxMVGhoaFHXJVTXFyslJQUS1U1HKNGjdKsWbP00UcfqUWLFs72lJQU7d+/X6WlpQHtD+/XlJSUo/Z7zb7jtYmNjVVUVFRtn07QWbFihUpKSnT++ecrLCxMYWFhWrhwoZ566imFhYUpOTmZfq4FzZo1U5cuXQK2de7cWYWFhZIO9dPx/p1ISUlRSUlJwP6qqirt3LnzpP4uTmdjx451Rom6du2q66+/Xnfeeacz+kk/14367NdjtTnZficQWRAREaFu3bpp3rx5zja/36958+YpIyPDYmXBzRijUaNGaebMmZo/f77atGkTsL9bt24KDw8P6Nf169ersLDQ6deMjAytXLky4H/C3NxcxcbGOr+cMjIyAo5R08YtfzcDBw7UypUrlZ+f77y6d++u7Oxs52f6+Zfr06fPEbeN2LBhg1q1aiVJatOmjVJSUgL6yOfzaenSpQH9XFpaqhUrVjht5s+fL7/fr549ezptFi1apMrKSqdNbm6uOnbsqCZNmtTZ+QWLPXv2KCQk8FddaGio/H6/JPq5rtRnv9bavyUntQQbtea1114zXq/XTJs2zaxZs8aMHDnSxMfHB1yVg0C33nqriYuLMwsWLDDbt293Xnv27HHa3HLLLaZly5Zm/vz5Zvny5SYjI8NkZGQ4+2suBx80aJDJz883c+bMMWecccZRLwcfO3asWbt2rZk6daqrLgc/msOvMjOGfq4Ny5YtM2FhYeYvf/mL2bhxo3n55ZdNdHS0+de//uW0eeSRR0x8fLx5++23zVdffWUuv/zyo162nJ6ebpYuXWo++eQT0759+4DLlktLS01ycrK5/vrrzapVq8xrr71moqOjT+vLwQ93ww03mObNmzuX3b/55psmMTHR3HPPPU4b+vnU7Nq1y3zxxRfmiy++MJLMY489Zr744guzefNmY0z99evixYtNWFiY+dvf/mbWrl1rJk6cyGX3Dc3TTz9tWrZsaSIiIkyPHj3MkiVLbJcU1CQd9fXiiy86bfbu3Wv++Mc/miZNmpjo6Gjzm9/8xmzfvj3gON9++60ZMmSIiYqKMomJieauu+4ylZWVAW0++ugjc95555mIiAjTtm3bgO9wo58GIvq5drz77rvm7LPPNl6v13Tq1Mk8//zzAfv9fr+57777THJysvF6vWbgwIFm/fr1AW127NhhrrnmGhMTE2NiY2PN7373O7Nr166ANl9++aXp27ev8Xq9pnnz5uaRRx6p83MLFj6fz9xxxx2mZcuWJjIy0rRt29b8+c9/DriMm34+NR999NFR/02+4YYbjDH126+vv/666dChg4mIiDBnnXWWmT179kmfj8eYw27XCQAA4EKsIQIAAK5HIAIAAK5HIAIAAK5HIAIAAK5HIAIAAK5HIAIAAK5HIAIAAK5HIAIAAK5HIAJgxYUXXqjRo0fbLsNhjNHIkSOVkJAgj8ej/Px82yUdU+vWrfXEE0/YLgM4rYTZLgAAgsGcOXM0bdo0LViwQG3btlViYqLtkgDUIwIRgNNGdXW1PB7PEU83PxFff/21mjVrpt69e9dBZQCCHVNmgItdeOGFuv3223XPPfcoISFBKSkpmjRpkrP/22+/PWL6qLS0VB6PRwsWLJAkLViwQB6PRx988IHS09MVFRWliy66SCUlJXr//ffVuXNnxcbG6tprr9WePXsCvr+qqkqjRo1SXFycEhMTdd999+nwxytWVFTo7rvvVvPmzdWoUSP17NnT+V5JmjZtmuLj4/XOO++oS5cu8nq9KiwsPOq5Lly4UD169JDX61WzZs30pz/9SVVVVZKkG2+8UbfddpsKCwvl8XjUunXrY/bZJ598on79+ikqKkppaWm6/fbbtXv3bmd/69at9eCDD+qaa65Ro0aN1Lx5c02dOjXgGIWFhbr88ssVExOj2NhYXXXVVSouLg5o8+677+qCCy5QZGSkEhMT9Zvf/CZg/549e3TTTTepcePGatmypZ5//vmA/Vu2bNFVV12l+Ph4JSQk6PLLL9e3337r7F+wYIF69OihRo0aKT4+Xn369NHmzZuPed7Aae+kHwcL4LQxYMAAExsbayZNmmQ2bNhgXnrpJePxeMzcuXONMcYUFBQYSeaLL75wPvPjjz8aSeajjz4yxhx64nWvXr3MJ598Yj7//HPTrl07M2DAADNo0CDz+eefm0WLFpmmTZsGPKV6wIABJiYmxtxxxx1m3bp15l//+peJjo4OeOL773//e9O7d2+zaNEis2nTJvPoo48ar9drNmzYYIwx5sUXXzTh4eGmd+/eZvHixWbdunVm9+7dR5znd999Z6Kjo80f//hHs3btWjNz5kyTmJhoJk6caIwxprS01DzwwAOmRYsWZvv27aakpOSo/bVp0ybTqFEj8/jjj5sNGzaYxYsXm/T0dHPjjTc6bVq1amUaN25sJk+ebNavX2+eeuopExoa6vRpdXW1Oe+880zfvn3N8uXLzZIlS0y3bt3MgAEDnGPMmjXLhIaGmgkTJpg1a9aY/Px88/DDDwd8R0JCgpk6darZuHGjmTx5sgkJCTHr1q0zxhizf/9+07lzZ3PTTTeZr776yqxZs8Zce+21pmPHjqaiosJUVlaauLg4c/fdd5tNmzaZNWvWmGnTppnNmzf/3H8ywGmLQAS42IABA0zfvn0Dtl1wwQVm3LhxxpiTC0Qffvih02by5MlGkvn666+dbTfffLPJysoK+O7OnTsbv9/vbBs3bpzp3LmzMcaYzZs3m9DQULN169aA+gYOHGjGjx9vjDkQiCSZ/Pz8457n//t//8907Ngx4LumTp1qYmJiTHV1tTHGmMcff9y0atXquMcZMWKEGTlyZMC2jz/+2ISEhJi9e/caYw6ElcGDBwe0+e1vf2uGDBlijDFm7ty5JjQ01BQWFjr7V69ebSSZZcuWGWOMycjIMNnZ2ceso1WrVua6665z3vv9fpOUlGSeffZZY4wx//znP48434qKChMVFWU++OADs2PHDiPJLFiw4LjnC7gJU2aAy51zzjkB75s1a6aSkpJfdJzk5GRFR0erbdu2Adt+etxevXrJ4/E47zMyMrRx40ZVV1dr5cqVqq6uVocOHRQTE+O8Fi5cqK+//tr5TERExBHn8FNr165VRkZGwHf16dNH5eXl+u677074HL/88ktNmzYtoJ6srCz5/X4VFBQEnMfhMjIytHbtWqeWtLQ0paWlOfu7dOmi+Ph4p01+fr4GDhx43FoOP2ePx6OUlBSnf7/88ktt2rRJjRs3dupMSEjQvn379PXXXyshIUE33nijsrKydOmll+rJJ5/U9u3bT7gfgNMRi6oBlwsPDw947/F45Pf7JclZnGwOW9dTWVn5s8fxeDzHPe6JKC8vV2hoqFasWKHQ0NCAfTExMc7PUVFRAUGnLpWXl+vmm2/W7bfffsS+li1b1tr3REVF/Wyb4/VveXm5unXrppdffvmIz51xxhmSpBdffFG333675syZo+nTp+vee+9Vbm6uevXqVQtnADQ8BCIAx1Tzy3P79u1KT0+XpFq9P8/SpUsD3i9ZskTt27dXaGio0tPTVV1drZKSEvXr1+8XfU/nzp31xhtvyBjjhKfFixercePGatGixQkf5/zzz9eaNWvUrl2747ZbsmTJEe87d+7s1LJlyxZt2bLFGSVas2aNSktL1aVLF0kHRn/mzZun3/3udydc20/rnD59upKSkhQbG3vMdunp6UpPT9f48eOVkZGhV155hUAE12LKDMAxRUVFqVevXnrkkUe0du1aLVy4UPfee2+tHb+wsFBjxozR+vXr9eqrr+rpp5/WHXfcIUnq0KGDsrOzNXz4cL355psqKCjQsmXLNHnyZM2ePfukvuePf/yjtmzZottuu03r1q3T22+/rYkTJ2rMmDEndYn+uHHj9Omnn2rUqFHKz8/Xxo0b9fbbb2vUqFEB7RYvXqwpU6Zow4YNmjp1qmbMmOGcV2Zmprp27ars7Gx9/vnnWrZsmYYPH64BAwaoe/fukqSJEyfq1Vdf1cSJE7V27VqtXLlSf/3rX0+4zuzsbCUmJuryyy/Xxx9/rIKCAi1YsEC33367vvvuOxUUFGj8+PHKy8vT5s2bNXfuXG3cuNEJbYAbEYgAHNcLL7ygqqoqdevWTaNHj9ZDDz1Ua8cePny49u7dqx49eignJ0d33HGHRo4c6ex/8cUXNXz4cN11113q2LGjrrjiCn322WcnPT3VvHlzvffee1q2bJnOPfdc3XLLLRoxYsRJh7tzzjlHCxcu1IYNG9SvXz+lp6drwoQJSk1NDWh31113afny5UpPT9dDDz2kxx57TFlZWZIOTG29/fbbatKkifr376/MzEy1bdtW06dPdz5/4YUXasaMGXrnnXd03nnn6aKLLtKyZctOuM7o6GgtWrRILVu21JVXXqnOnTtrxIgR2rdvn2JjYxUdHa1169Zp2LBh6tChg0aOHKmcnBzdfPPNJ9UfwOnEYw5fHAAA+EVat26t0aNHB9VjSQD8PEaIAACA6xGIAACA6zFlBgAAXI8RIgAA4HoEIgAA4HoEIgAA4HoEIgAA4HoEIgAA4HoEIgAA4HoEIgAA4HoEIgAA4Hr/H1ZxWfhmEvEWAAAAAElFTkSuQmCC\n"
          },
          "metadata": {}
        }
      ],
      "source": [
        "import matplotlib.pyplot as plt\n",
        "\n",
        "# x axis values\n",
        "x = [i for i in range(n_epoches)]\n",
        "# corresponding y axis values\n",
        "y = losses\n",
        "\n",
        "# plotting the points\n",
        "plt.plot(x, y)\n",
        "\n",
        "# naming the x axis\n",
        "plt.xlabel('number of epoches')\n",
        "# naming the y axis\n",
        "plt.ylabel('loss')\n",
        "\n",
        "# function to show the plot\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jMDGlNqnwZUu"
      },
      "source": [
        "<font face=\"Times New Roman\"><div id=\"2\">\n",
        "# <font color=\"#800080\" size=6>**2. Beyond Linear Regression**</font>\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OZyxj4cjnzW_"
      },
      "source": [
        "<font face=\"Times New Roman\"><div id=\"2-1\">\n",
        "## <font color=\"#800080\" size=6>**2-1. Elastic Net**</font>\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VQ5QM-42DA_1"
      },
      "source": [
        "#### <font color=\"#008080\" face=\"Times New Roman\" size=4>**Model**</font>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "id": "Cb9U5AFnDA_2"
      },
      "outputs": [],
      "source": [
        "class Regression:\n",
        "\n",
        "    def __init__(self, regularization, lr, epoch):\n",
        "        self.m = None #samples\n",
        "        self.n = None #features\n",
        "        self.w = None #weight\n",
        "        self.b = None #bias\n",
        "        self.regularization = regularization #penalty object\n",
        "        self.lr = lr #learning rate\n",
        "        self.epoch = epoch #iteration\n",
        "\n",
        "    def __calculate_cost(self, y, y_pred):\n",
        "        return (1 / (2*self.m)) * np.sum(np.square(y_pred-y)) + self.regularization(self.w)\n",
        "\n",
        "    def __hypothesis(self, w, X):\n",
        "        return np.dot(X, w)\n",
        "\n",
        "    def __initialization(self, X):\n",
        "        X = np.insert(X, 0, 1, axis=1)\n",
        "        self.m, self.n = X.shape\n",
        "        self.w = np.zeros((self.n,1))\n",
        "        return X\n",
        "\n",
        "    def __update_parameters(self, X, y, y_pred):\n",
        "        dw = (1/self.m) * np.dot(X.T, (y_pred - y)) + self.regularization.derivation(self.w)\n",
        "        self.w = self.w - self.lr * dw\n",
        "        return True\n",
        "\n",
        "    def fit(self, X, y):\n",
        "        X = self.__initialization(X)\n",
        "        for e in range(1, self.epoch+1):\n",
        "            y_pred = self.__hypothesis(self.w, X)\n",
        "            cost = self.__calculate_cost(y, y_pred)\n",
        "            self.__update_parameters(X, y, y_pred)\n",
        "            if e % 5000 == 0:\n",
        "#                 print(f\"The Cost in iteration {e}----->{cost} :)\")\n",
        "                pass\n",
        "\n",
        "        return True\n",
        "\n",
        "    def predict(self, X_test):\n",
        "        X_test = np.insert(X_test, 0 , 1, axis= 1)\n",
        "        y_pred = self.__hypothesis(self.w, X_test)\n",
        "        return y_pred"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "id": "uxYKZQ2uCL3W"
      },
      "outputs": [],
      "source": [
        "class ElasticPenalty:\n",
        "\n",
        "    def __init__(self, l = 0.1, l_ratio = 0.5):\n",
        "        self.l = l\n",
        "        self.l_ratio = l_ratio\n",
        "\n",
        "    def __call__(self, w):\n",
        "        l1_contribution = self.l_ratio * self.l * np.sum(np.abs(w))\n",
        "        l2_contribution = (1 - self.l_ratio) * self.l * 0.5 * np.sum(np.square(w))\n",
        "        return (l1_contribution + l2_contribution)\n",
        "\n",
        "    def derivation(self, w):\n",
        "        l1_derivation = self.l * self.l_ratio * np.sign(w)\n",
        "        l2_derivation = self.l * (1 - self.l_ratio) * w\n",
        "        return (l1_derivation + l2_derivation)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "id": "11rH2ctXCL3X"
      },
      "outputs": [],
      "source": [
        "class ElasticNet(Regression):\n",
        "\n",
        "    def __init__(self, l, l_ratio, lr, epoch):\n",
        "        self.regularization = ElasticPenalty(l,l_ratio)\n",
        "        super().__init__(self.regularization, lr, epoch)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UYJC961EDA_2"
      },
      "source": [
        "<font face=\"Times New Roman\"><div id=\"2-1-1\">\n",
        "### <font color=\"#800080\" size=5>**2-1-1. Lasso VS Ridge**</font>\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 449
        },
        "id": "vx27gm_9DA_2",
        "outputId": "58e66a4c-baf0-4f15-88bd-91ea91189fa2"
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ],
            "image/png": "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\n"
          },
          "metadata": {}
        }
      ],
      "source": [
        "from sklearn.datasets import make_regression\n",
        "\n",
        "# Creating the dataset\n",
        "X, y = make_regression(n_samples=50000, n_features=8, noise=5)\n",
        "y = y[:, np.newaxis]\n",
        "\n",
        "losses = []\n",
        "for i in range(11):\n",
        "    parameters = {\n",
        "        \"l_ratio\" : i * 0.1,\n",
        "        \"l\" : 0.1,\n",
        "        \"lr\" : 0.001,\n",
        "        \"epoch\" : 10000\n",
        "    }\n",
        "    model = ElasticNet(**parameters)\n",
        "    model.fit(X, y)\n",
        "    y_pred = model.predict(X)\n",
        "    losses.append(mse_loss(y_pred, y))\n",
        "\n",
        "x = [i * 0.1 for i in range(11)]\n",
        "y = losses\n",
        "plt.plot(x, y)\n",
        "plt.xlabel('l ratio')\n",
        "plt.ylabel('loss')\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 449
        },
        "id": "3grZumnHwZU2",
        "outputId": "d15c399f-8890-47ee-ac4e-843f3007354b"
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ],
            "image/png": "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NWnSpLIo2+WU5D4/9NBDOnPmjG677TYZhqGsrCw98cQTmjBhQlmUXGFc770wJSVFly9flre3d6m/JjNIQCFefvllLVu2TKtXr5aXl5fZ5ZQbqampGjx4sN58800FBQWZXU65ZrfbVb16dc2fP1+RkZF68MEH9fzzz+v11183u7Ry5dtvv9VLL72k1157TTt27NCqVau0Zs0aTZ482ezS8Acxg1SGgoKC5ObmpqSkpDzHk5KSVKNGjUKfU6NGjWKNR46S3OtrZs6cqZdffllff/21WrRo4cgyXV5x7/PBgwcVHx+vXr165R6z2+2SJHd3d8XGxio8PNyxRbugkvx5DgkJkYeHh9zc3HKPNW7cWImJicrIyJDNZnNoza6oJPd54sSJGjx4sIYPHy5Jat68uS5duqTHH39czz//vKxW5iFKw/XeCwMCAhwyeyQxg1SmbDabIiMjtX79+txjdrtd69evV4cOHQp9TocOHfKMl6SvvvrquuORoyT3WpKmT5+uyZMna+3atWrbtm1ZlOrSinufIyIitHv3bsXExOQ+evfurS5duigmJkZhYWFlWb7LKMmf51tvvVVxcXG5AVSSDhw4oJCQEMLRdZTkPqelpRUIQddCqcFXnZYaU94LHbb8G4VatmyZ4enpabzzzjvG3r17jccff9yoVKmSkZiYaBiGYQwePNgYN25c7vgff/zRcHd3N2bOnGns27fPmDRpEtv8i6i49/rll182bDab8eGHHxonT57MfaSmppp1CS6huPc5P3axFU1x7/PRo0cNf39/46mnnjJiY2ONzz77zKhevbrx4osvmnUJLqG493nSpEmGv7+/8f777xuHDh0y1q1bZ4SHhxsPPPCAWZfgElJTU42dO3caO3fuNCQZs2bNMnbu3GkcOXLEMAzDGDdunDF48ODc8de2+Y8dO9bYt2+fMXfuXLb5l0ezZ882ateubdhsNqNdu3bGli1bcn93xx13GEOGDMkzfvny5UbDhg0Nm81mNG3a1FizZk0ZV+y6inOv69SpY0gq8Jg0aVLZF+5iivtn+rcISEVX3Pu8adMm45ZbbjE8PT2N+vXrG1OmTDGysrLKuGrXU5z7nJmZafzzn/80wsPDDS8vLyMsLMx48sknjfPnz5d94S5kw4YNhf59e+3eDhkyxLjjjjsKPKdVq1aGzWYz6tevb7z99tsOrdFiGMwBAgAA/BZrkAAAAPIhIAEAAORDQAIAAMiHgAQAAJAPAQkAACAfAhIAAEA+BCQAAIB8CEgAAAD5EJAAlBudO3fWqFGjyuz1hg4dqj59+pTZ6wEoO+5mFwAAzi4+Pl716tXTzp071apVq9zjr776Kl9ICpRTBCQAFVZGRsYf+mb7wMDAUqwGgDPhIzYAFcY///lPtWrVSm+99Zbq1asnLy8vSdLatWt12223qVKlSqpatap69uypgwcP5j6vXr16kqTWrVvLYrGoc+fOkgp+xJaenq6//vWvql69ury8vHTbbbfpp59+KrPrA1B6CEgAKpS4uDitXLlSq1atUkxMjCTp0qVLGjNmjLZv367169fLarWqb9++stvtkqRt27ZJkr7++mudPHlSq1atKvTczz77rFauXKlFixZpx44datCggbp166Zz586VybUBKD18xAagQsnIyNC7776ratWq5R6LiorKM2bhwoWqVq2a9u7dq2bNmuWOrVq1qmrUqFHoeS9duqR58+bpnXfeUffu3SVJb775pr766istWLBAY8eOddAVAXAEZpAAVCh16tTJE44k6ddff9XAgQNVv359BQQEqG7dupKko0ePFvm8Bw8eVGZmpm699dbcYx4eHmrXrp327dtXKrUDKDvMIAGoUHx9fQsc69Wrl+rUqaM333xToaGhstvtatasmTIyMkyoEIAzYAYJQIV29uxZxcbG6u9//7u6du2qxo0b6/z583nGXNvplp2dfd3zhIeHy2az6ccff8w9lpmZqZ9++klNmjRxTPEAHIYZJAAVWuXKlVW1alXNnz9fISEhOnr0qMaNG5dnTPXq1eXt7a21a9eqVq1a8vLyKrDF39fXV3/+8581duxYValSRbVr19b06dOVlpamYcOGleUlASgFzCABqNCsVquWLVum6OhoNWvWTKNHj9aMGTPyjHF3d9d///tfvfHGGwoNDdV9991X6LlefvllRUVFafDgwWrTpo3i4uL05ZdfqnLlymVxKQBKkcWgDSwAAEAezCABAADkQ0ACAADIh4AEAACQDwEJAAAgHwISAABAPgQkAACAfAhIAAAA+RCQAAAA8iEgAQAA5ENAAgAAyIeABAAAkM//Az2T3Gm5Rs9nAAAAAElFTkSuQmCC\n"
          },
          "metadata": {}
        }
      ],
      "source": [
        "# Creating the dataset\n",
        "X, y = make_regression(n_samples=5000, n_features=3, noise=3)\n",
        "y = y[:, np.newaxis]\n",
        "\n",
        "for i in range (5000):\n",
        "    if i % 4 == 0:\n",
        "        X[i] = X[i] * 20\n",
        "        y[i] = y[i] * 20\n",
        "losses = []\n",
        "for i in range(11):\n",
        "    parameters = {\n",
        "        \"l_ratio\" : i * 0.1,\n",
        "        \"l\" : 0.1,\n",
        "        \"lr\" : 0.0001,\n",
        "        \"epoch\" : 10000\n",
        "    }\n",
        "    model = ElasticNet(**parameters)\n",
        "    model.fit(X, y)\n",
        "    y_pred = model.predict(X)\n",
        "    losses.append(mse_loss(y_pred, y))\n",
        "x = [i * 0.1 for i in range(11)]\n",
        "y = losses\n",
        "plt.plot(x, y)\n",
        "plt.xlabel('l ratio')\n",
        "plt.ylabel('loss')\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Generating polynomial dataset\n",
        "from sklearn.preprocessing import PolynomialFeatures\n",
        "\n",
        "X = np.random.randn(5000, 10)\n",
        "poly = PolynomialFeatures(degree=3)\n",
        "X = poly.fit_transform(X)\n",
        "y = np.random.randn(5000, 1)\n",
        "\n",
        "# Introducing collinearity between features\n",
        "for i in range(X.shape[1]):\n",
        "  X[:,i] = X[:,i] + 0.5*X[:,i-1]\n",
        "\n",
        "# Defining model parameters\n",
        "losses = []\n",
        "for i in range(11):\n",
        "  parameters = {\n",
        "    \"l_ratio\" : i * 0.1,\n",
        "    \"l\" : 1, # Increased regularization strength\n",
        "    \"lr\" : 0.0001,\n",
        "    \"epoch\" : 10000\n",
        "  }\n",
        "\n",
        "  # Fitting model\n",
        "  model = ElasticNet(**parameters)\n",
        "  model.fit(X, y)\n",
        "\n",
        "  # Making predictions and evaluating loss\n",
        "  y_pred = model.predict(X)\n",
        "  losses.append(mse_loss(y_pred, y))\n",
        "\n",
        "# Plotting losses\n",
        "x = [i * 0.1 for i in range(11)]\n",
        "y = losses\n",
        "plt.plot(x, y)\n",
        "plt.xlabel('l ratio')\n",
        "plt.ylabel('loss')\n",
        "plt.show()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 449
        },
        "id": "5gdYX5VhCR-o",
        "outputId": "a995bd36-a6ce-44ce-8e33-75901277599b"
      },
      "execution_count": 19,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ],
            "image/png": "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SfrP//xPr2Pdf//9XuUWLlzYcSfaCoW1t9hoQQIAwD/8HpAWLVqk+++/XxMmTND3v/99rVixQl27dtWrr77aZPnVq1frV7/6lUaPHq0BAwbogQce0OjRo/Wb3/zGLNOrVy8lJCSYj/fee09paWn64Q9/6HWsrl27epWLiorq0HNtiWqXWwdPVEhiFm0AAPzFrwGpqqpK27ZtU1ZWlrnNarUqKytL+fn5Te5TWVkph8PhtS0iIkKbN29u9j3WrFmje++9VxaLxeu1N954Q3Fxcbrssss0c+ZMnT59utm6VlZWyul0ej06QvHxM3K5DdnDrerd3d4h7wEAAM4t3J9vfvToUblcLsXHx3ttj4+P1549e5rcJzs7W4sWLdK1116rtLQ05eXlae3atXK5XE2WX7dunU6cOKF77rnHa/udd96pfv36KSkpSZ9//rkeffRRffnll1q7dm2Tx1mwYIEef/zx1p9kK9VfYsRqtZynNAAA6Ah+DUhtsWTJEt1///0aNGiQLBaL0tLSNGHChGZvyb3yyisaNWqUkpKSvLZPnDjR/Hnw4MFKTEzU9ddfr3379iktLa3RcWbOnKmcnBzzudPpVHJycjudVZ2iY7X9j+igDQCA3/j1FltcXJzCwsJUWlrqtb20tFQJCQlN7tOrVy+tW7dO5eXlKiws1J49exQZGakBAwY0KltYWKgPPvhA991333nrkpGRIUnau3dvk6/b7XZFRUV5PTqCOYKNJUYAAPAbvwYkm82moUOHKi8vz9zmdruVl5enzMzMc+7rcDjUp08f1dTU6N1339WYMWMalXnttdfUu3dv3XTTTeety86dOyVJiYmJrTuJdlZZ45YtzEoLEgAAfuT3W2w5OTkaP368hg0bpuHDh2vx4sUqLy/XhAkTJEl33323+vTpowULFkiStmzZouLiYqWnp6u4uFiPPfaY3G63pk+f7nVct9ut1157TePHj1d4uPdp7tu3T2+++aZGjx6tnj176vPPP9fUqVN17bXX6vLLL/fNiTdj/m2X6bFbL1WN2+3XegAAEMr8HpDGjRunI0eOaO7cuSopKVF6erpyc3PNjttFRUWyWusauioqKjR79mzt379fkZGRGj16tFavXq2YmBiv437wwQcqKirSvffe2+g9bTabPvjgAzOMJScna+zYsZo9e3aHnmtLhVktCrOG+bsaAACELIthGIa/KxGInE6noqOjVVZW1inmTwIAAOfX0u9vv08UCQAA0NkQkAAAABogIAEAADRAQAIAAGiAgAQAANAAAQkAAKABAhIAAEADBCQAAIAGCEgAAAANEJAAAAAaICABAAA0QEACAABoINzfFQhUnjV+nU6nn2sCAABayvO97fkebw4BqY1OnjwpSUpOTvZzTQAAQGudPHlS0dHRzb5uMc4XodAkt9utgwcPqnv37rJYLO12XKfTqeTkZB04cEBRUVHtdlw0xrX2Da6zb3CdfYPr7BsdeZ0Nw9DJkyeVlJQkq7X5nka0ILWR1WpV3759O+z4UVFR/OXzEa61b3CdfYPr7BtcZ9/oqOt8rpYjDzppAwAANEBAAgAAaICA1MnY7XbNmzdPdrvd31UJelxr3+A6+wbX2Te4zr7RGa4znbQBAAAaoAUJAACgAQISAABAAwQkAACABghIAAAADRCQ/GD58uXq37+/HA6HMjIytHXr1nOW/8Mf/qBBgwbJ4XBo8ODBev/9931U08DXmmv90ksv6Qc/+IF69OihHj16KCsr67y/G5zV2s+0x1tvvSWLxaLbbrutYysYJFp7nU+cOKHJkycrMTFRdrtd3/ve9/j3owVae50XL16siy++WBEREUpOTtbUqVNVUVHho9oGpo8//li33HKLkpKSZLFYtG7duvPus2nTJl155ZWy2+0aOHCgVq5c2bGVNOBTb731lmGz2YxXX33V+Ne//mXcf//9RkxMjFFaWtpk+b///e9GWFiYsXDhQmPXrl3G7NmzjS5duhhffPGFj2seeFp7re+8805j+fLlxo4dO4zdu3cb99xzjxEdHW18++23Pq55YGntdfYoKCgw+vTpY/zgBz8wxowZ45vKBrDWXufKykpj2LBhxujRo43NmzcbBQUFxqZNm4ydO3f6uOaBpbXX+Y033jDsdrvxxhtvGAUFBcaGDRuMxMREY+rUqT6ueWB5//33jVmzZhlr1641JBl/+tOfzll+//79RteuXY2cnBxj165dxtKlS42wsDAjNze3w+pIQPKx4cOHG5MnTzafu1wuIykpyViwYEGT5X/84x8bN910k9e2jIwM4+c//3mH1jMYtPZaN1RTU2N0797dWLVqVUdVMSi05TrX1NQYI0aMMF5++WVj/PjxBKQWaO11fuGFF4wBAwYYVVVVvqpiUGjtdZ48ebLxb//2b17bcnJyjKuvvrpD6xlMWhKQpk+fblx66aVe28aNG2dkZ2d3WL24xeZDVVVV2rZtm7KyssxtVqtVWVlZys/Pb3Kf/Px8r/KSlJ2d3Wx5nNWWa93Q6dOnVV1drdjY2I6qZsBr63V+4okn1Lt3b/3sZz/zRTUDXluu83//938rMzNTkydPVnx8vC677DI9/fTTcrlcvqp2wGnLdR4xYoS2bdtm3obbv3+/3n//fY0ePdondQ4V/vguZLFaHzp69KhcLpfi4+O9tsfHx2vPnj1N7lNSUtJk+ZKSkg6rZzBoy7Vu6NFHH1VSUlKjv5So05brvHnzZr3yyivauXOnD2oYHNpynffv368PP/xQP/3pT/X+++9r7969evDBB1VdXa158+b5otoBpy3X+c4779TRo0d1zTXXyDAM1dTUaNKkSfrVr37liyqHjOa+C51Op86cOaOIiIh2f09akIAmPPPMM3rrrbf0pz/9SQ6Hw9/VCRonT57UXXfdpZdeeklxcXH+rk5Qc7vd6t27t373u99p6NChGjdunGbNmqUVK1b4u2pBZdOmTXr66af129/+Vtu3b9fatWu1fv16zZ8/399VwwWiBcmH4uLiFBYWptLSUq/tpaWlSkhIaHKfhISEVpXHWW251h6//vWv9cwzz+iDDz7Q5Zdf3pHVDHitvc779u3TN998o1tuucXc5na7JUnh4eH68ssvlZaW1rGVDkBt+TwnJiaqS5cuCgsLM7ddcsklKikpUVVVlWw2W4fWORC15TrPmTNHd911l+677z5J0uDBg1VeXq6JEydq1qxZslpph2gPzX0XRkVFdUjrkUQLkk/ZbDYNHTpUeXl55ja32628vDxlZmY2uU9mZqZXeUnauHFjs+VxVluutSQtXLhQ8+fPV25uroYNG+aLqga01l7nQYMG6YsvvtDOnTvNx6233qqRI0dq586dSk5O9mX1A0ZbPs9XX3219u7dawZQSfrqq6+UmJhIOGpGW67z6dOnG4UgTyg1WOq03fjlu7DDun+jSW+99ZZht9uNlStXGrt27TImTpxoxMTEGCUlJYZhGMZdd91lzJgxwyz/97//3QgPDzd+/etfG7t37zbmzZvHMP8Wau21fuaZZwybzWb88Y9/NA4dOmQ+Tp486a9TCAitvc4NMYqtZVp7nYuKiozu3bsbDz30kPHll18a7733ntG7d2/jySef9NcpBITWXud58+YZ3bt3N37/+98b+/fvN/7yl78YaWlpxo9//GN/nUJAOHnypLFjxw5jx44dhiRj0aJFxo4dO4zCwkLDMAxjxowZxl133WWW9wzznzZtmrF7925j+fLlDPMPRkuXLjVSUlIMm81mDB8+3Pjkk0/M1374wx8a48eP9yr/zjvvGN/73vcMm81mXHrppcb69et9XOPA1Zpr3a9fP0NSo8e8efN8X/EA09rPdH0EpJZr7XX+xz/+YWRkZBh2u90YMGCA8dRTTxk1NTU+rnXgac11rq6uNh577DEjLS3NcDgcRnJysvHggw8ax48f933FA8hf//rXJv+99Vzb8ePHGz/84Q8b7ZOenm7YbDZjwIABxmuvvdahdbQYBm2AAAAA9dEHCQAAoAECEgAAQAMEJAAAgAYISAAAAA0QkAAAABogIAEAADRAQAIAAGiAgAQAANAAAQlA0Ljuuus0ZcoUn73fPffco9tuu81n7wfAd8L9XQEA6Oy++eYbpaamaseOHUpPTze3L1myhAVJgSBFQAIQsqqqqi5oZfvo6Oh2rA2AzoRbbABCxmOPPab09HS9/PLLSk1NlcPhkCTl5ubqmmuuUUxMjHr27Kmbb75Z+/btM/dLTU2VJF1xxRWyWCy67rrrJDW+xVZZWalHHnlEvXv3lsPh0DXXXKNPP/3UZ+cHoP0QkACElL179+rdd9/V2rVrtXPnTklSeXm5cnJy9NlnnykvL09Wq1W333673G63JGnr1q2SpA8++ECHDh3S2rVrmzz29OnT9e6772rVqlXavn27Bg4cqOzsbH333Xc+OTcA7YdbbABCSlVVlV5//XX16tXL3DZ27FivMq+++qp69eqlXbt26bLLLjPL9uzZUwkJCU0et7y8XC+88IJWrlypUaNGSZJeeuklbdy4Ua+88oqmTZvWQWcEoCPQggQgpPTr188rHEnS119/rZ/85CcaMGCAoqKi1L9/f0lSUVFRi4+7b98+VVdX6+qrrza3denSRcOHD9fu3bvbpe4AfIcWJAAhpVu3bo223XLLLerXr59eeuklJSUlye1267LLLlNVVZUfagigM6AFCUBIO3bsmL788kvNnj1b119/vS655BIdP37cq4xnpJvL5Wr2OGlpabLZbPr73/9ubquurtann36q73//+x1TeQAdhhYkACGtR48e6tmzp373u98pMTFRRUVFmjFjhleZ3r17KyIiQrm5uerbt68cDkejIf7dunXTAw88oGnTpik2NlYpKSlauHChTp8+rZ/97Ge+PCUA7YAWJAAhzWq16q233tK2bdt02WWXaerUqfqv//ovrzLh4eF6/vnn9eKLLyopKUljxoxp8ljPPPOMxo4dq7vuuktXXnml9u7dqw0bNqhHjx6+OBUA7chiMA0sAACAF1qQAAAAGiAgAQAANEBAAgAAaICABAAA0AABCQAAoAECEgAAQAMEJAAAgAYISAAAAA0QkAAAABogIAEAADRAQAIAAGjg/wOQz4WipYRxTwAAAABJRU5ErkJggg==\n"
          },
          "metadata": {}
        }
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [
        "rYaiPL1plrDm",
        "swwrxuSMAESj",
        "gYuiA7fFAESk",
        "helJaWTOAESk",
        "0BrjWqO-AESk",
        "E5LZv8WxAESl",
        "gSvKw0pdAESm",
        "DCicBNv3AESm",
        "rpEZrgzGAESn",
        "68iIHGEgAl1w",
        "hXPBaNz8Al1x",
        "M0vNkt4dAl1x",
        "_8eHSEgJAl1x",
        "14oWGLnbAl1y",
        "osVXNTRxAl1y",
        "UNVQE4NhAl1z",
        "SULBwRA6Al10",
        "OZyxj4cjnzW_",
        "eVbZVyBbDA_0",
        "8Iel5jWADA_0",
        "sk45TUlPDA_1",
        "Jsg8bozFDA_1",
        "VQ5QM-42DA_1",
        "UYJC961EDA_2",
        "3pZCWtkeo2Q_",
        "BG6JDKXAKthv",
        "I3TA7qSXJJug",
        "vORapzaoJJug",
        "2JNOCPY3JJuh",
        "3bDvO3dZJXLK",
        "DdttC2gIJhFv",
        "d1zcyxjIJnxg",
        "PcxB-PgbJ1FT",
        "TOn8ae25J-Px",
        "RnJ3PbxLKkyu",
        "JGusVztLLKHA",
        "D2hHo3jxLKHA",
        "GYdgEkdDLKHB",
        "L-YMqtB5LKHB",
        "B-nGWBOrIrDe",
        "1kwiWMyhL0Cw",
        "EcUj0p-zL0Cw",
        "ZpIDH-M4L0Cx",
        "950JsRNjMAny",
        "iOPf8PsJMHZ4",
        "a6xyh9qQMNUh",
        "HBT59RLpIyUY",
        "XjRZm_smMaVe",
        "GjQTvUPCNGiw",
        "FnHgYu6jNcNn",
        "UuhpDpAfNhYJ",
        "sb5j_Pm8NrmT",
        "0fK-03_HNula",
        "sq_TTicpN0Rz",
        "1TgrioWuqBHB",
        "DXDtIWVI8y1_",
        "fnaXSgAZ-RoF",
        "OuleUT7a-aLd",
        "v3vX2AMI-jCL",
        "NB7H40DRqdBB",
        "0VlisYKK1BZ_",
        "lDvUSGJx15Dj",
        "PHHocSy32QI1",
        "Q7t6YQtj2Kgg",
        "n2JfuA9Wrqc4",
        "5mJ6zlBgsQVA",
        "TukJ4C4HsQVA",
        "f57VmUBasQVA",
        "HX4ZzxDNsQVB",
        "ze7ht2dosQVB",
        "vkmW7nLxtTbU",
        "VEqcnt5hwNdd",
        "fSjtED4lwXGX",
        "8p7waG2NwXN_",
        "0RYjgiwjzwKx",
        "LBfyqilLwXVo",
        "XDcH1G2wxDoG"
      ],
      "provenance": []
    },
    "kernelspec": {
      "display_name": "local-venv",
      "language": "python",
      "name": "local-venv"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.10.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}